#include "coroutineC.h"

// 协程入口包装函数
static void coroutine_entry(int id)
{
    Scheduler* s = GetInstance();
    Coroutine* co = s->coroutines[id];
    co->func(co->arg);  // 执行用户函数

    // 函数执行完毕
    co->state = COROUTINE_DEAD;
    s->current_id = -1;

    // 自动切换回主流程
    setcontext(&s->main_ctx);
}

int coroutine_create(int fd,coroutine_func func, void* arg)
{
    Scheduler* s = GetInstance();
    static int id = 0;
    Coroutine* co = malloc(sizeof(Coroutine));
    co->fd = fd;
    co->id = id;
    co->func = func;
    co->arg = arg;
    co->state = COROUTINE_READY;

    // 初始化上下文
    getcontext(&co->ctx);
    co->ctx.uc_stack.ss_sp = co->stack;
    co->ctx.uc_stack.ss_size = STACK_SIZE;
    co->ctx.uc_link = &s->main_ctx; // 执行完后返回主流程

    // 设置入口函数
    makecontext(&co->ctx, (void(*)(void))coroutine_entry, 1, id);   
    s->coroutines[id] = co;
    s->id_max = id;
    int res = id++;
    return res;
}

void coroutine_yield() {
    Scheduler* s = GetInstance();
    int current_id = s->current_id;
    if (current_id == -1) return;

    Coroutine* co = s->coroutines[current_id];
    co->state = COROUTINE_SUSPEND;
    s->current_id = -1;

    // 保存当前上下文并切换回主流程
    swapcontext(&co->ctx, &s->main_ctx);
}

void coroutine_resume(int id) {
    Scheduler* s = GetInstance();
    if (s->coroutines[id]->state != COROUTINE_READY && s->coroutines[id]->state != COROUTINE_SUSPEND) return;   
    s->current_id = id;
    Coroutine* co = s->coroutines[id];
    co->state = COROUTINE_RUNNING;
    
    // 从主流程切换到协程
    swapcontext(&s->main_ctx, &co->ctx);
}